#pragma once

#include "TinyTimer.h"
#include <map>
#include <string>
#include "Functor.h"
#include "TinyThread.h"

template < typename T = long>
class CTinyTimerPool:public Loki::ObjectLevelLockable<CTinyTimerPool <T> >
{
public:
	CTinyTimerPool(void):m_ticketCount(0)
	{
		//start a thread to check timer
		m_timerCountDownThread = new TinyCC::CTinyThread( this, &CTinyTimerPool<T>::countDown, (void*)this );
	}
	virtual ~CTinyTimerPool(void)
	{
		//close thread first
		m_timerCountDownThread->normalExit();
	}
private:
	std::map< T, CTinyTimer<T>* > m_mapAliveTimer;			//list of ALive timer 
	long m_ticketCount;
	TinyCC::CTinyThread * m_timerCountDownThread;
public:
	bool requestTimer(T& timerID, long interval =0)
	{
		return false;
	}

	bool requestTimer(T& timerID, Loki::Functor<void,LOKI_TYPELIST_1( T& ) >* callbackFun, long interval =0, bool active = false)
	{
		//Lock lock(this);

		CTinyTimerID<T> tempTimerID;
		timerID = tempTimerID.getID();
		CTinyTimer<T> *tempTimer = new CTinyTimer<T>(timerID,callbackFun,interval,active);
		m_mapAliveTimer.insert(std::pair< T, CTinyTimer<T>* >(timerID,tempTimer));
		

		if(active == true)
			tempTimer->start();
		return true;
	}

	template<class ObjPointer,class MemFunPointer>
	bool requestTimer(ObjPointer& pObj,T& timerID, MemFunPointer pMemFunc, long interval, bool active = false)
	{
		Loki::Functor<void,LOKI_TYPELIST_1( T& ) >* pFunctor=new Loki::Functor<void,LOKI_TYPELIST_1( T& ) >(pObj, pMemFunc);
		return ( requestTimer( timerID, pFunctor, interval,active ) != NULL );
	}
	bool returnTimer(T& timerID)
	{
		Lock lock(this);
		std::map<T, CTinyTimer<T>* >::iterator it = m_mapAliveTimer.begin();
		if(it != m_mapAliveTimer.end())
		{
			m_mapAliveTimer.erase(it);
			return true;
		}
		return false;
	}

	bool starTimer(T& TimerID, long interval)
	{
		Lock lock(this);

		std::map<T, CTinyTimer<T>* >::iterator it = m_mapAliveTimer.begin();
		if(it != m_mapAliveTimer.end())
		{
			it->second.start(interval);
			return true;
		}
		return false;
	}

	bool stopTimer(T& TimerID)
	{
		Lock lock(this);

		std::map<T, CTinyTimer<T>* >::iterator it = m_mapAliveTimer.begin();
		if(it != m_mapAliveTimer.end())
		{
			it->second->stop();
			return true;
		}
		return false;
	}

	template<class ObjPointer,class MemFunPointer>
	bool regTimerHandle(ObjPointer& pObj,T& timerID, MemFunPointer pMemFunc)
	{
		Lock lock(this);

		Loki::Functor<void,LOKI_TYPELIST_1( T& ) >* pFunctor=new Loki::Functor<void,LOKI_TYPELIST_1( T& ) >(pObj, pMemFunc);
		return ( requestTimer( timerID, pFunctor) != NULL );
	}

	bool regTimerHandle(T& TimerID, Loki::Functor<void,LOKI_TYPELIST_1(T&)>* callbackFun)
	{
		return false;
	}

	void countDown(void* param)
	{
	//	Lock lock(this);

		while(true)
		{
			if(m_ticketCount ==0)
				m_ticketCount = GetTickCount();

			Sleep(2000);

			for(std::map<T,CTinyTimer<T>* >::iterator it=m_mapAliveTimer.begin();it!=m_mapAliveTimer.end();++it)
			{
				if(it->second->isAlive() == true)
					it->second->countDown(GetTickCount()-m_ticketCount);
			}
			m_ticketCount = GetTickCount();
		}
	}
};

